package top.korori.sv.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.korori.common.enums.IsDel;
import top.korori.common.enums.StatusCode;
import top.korori.common.exception.BizException;
import top.korori.common.model.PageData;
import top.korori.common.utils.EnumUtils;
import top.korori.oss.entity.res.CosTmpKeyVo;
import top.korori.oss.service.CosService;
import top.korori.sv.entity.*;
import top.korori.sv.entity.bo.*;
import top.korori.sv.entity.vo.SvUserWorkVo;
import top.korori.sv.entity.vo.SvWorkVo;
import top.korori.sv.entity.vo.SysSvWorkVo;
import top.korori.sv.enums.*;
import top.korori.sv.mapper.*;
import top.korori.sv.service.SvWorkService;
import top.korori.sv.uitls.SvSecurityUtil;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;


/**
 * 作品 服务实现类
 *
 * @author korori
 */
@Service
@AllArgsConstructor
public class SvWorkServiceImpl extends ServiceImpl<SvWorkMapper, SvWork> implements SvWorkService {

    private final SvWorkLikeMapper svWorkLikeMapper;

    private final SvWorkStarMapper svWorkStarMapper;

    private final SvWorkBrowseMapper svWorkBrowseMapper;

    private final CosService cosService;

    private final SvUserMapper svUserMapper;

    @Override
    public SvUserWorkVo push(SvWorkAddBo svWorkAddBo) {
        SvWork svWork = BeanUtil.copyProperties(svWorkAddBo, SvWork.class);
        svWork.setUserId(SvSecurityUtil.getUserId());
        svWork.setStatus(SvWorkStatusEnum.NORMAL.getCode());

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd/");
        String datePath = LocalDate.now().format(formatter);
        String outObj = "workCover/" + datePath + IdUtil.fastSimpleUUID() + ".jpg";

        if (ObjUtil.isNull(svWorkAddBo.getCover())) {
            String snapshot = cosService.snapshot(svWorkAddBo.getUrl(), outObj, "1");
            svWork.setCover(snapshot);
        }

        this.save(svWork);
        return BeanUtil.copyProperties(svWork, SvUserWorkVo.class);
    }


    @Override
    public PageData<SvUserWorkVo> getHoneWorks(SvHomeWorkGetBo req) {

        Page<SvUserWorkVo> svWorkVoPage = new Page<>(req.getPageNum(), req.getPageSize());

        Page<SvUserWorkVo> page = baseMapper.getHomeWorkExtUserList(svWorkVoPage);

        PageData<SvUserWorkVo> svWorkVoPageData = new PageData<>();
        svWorkVoPageData.setTotal(page.getTotal());
        svWorkVoPageData.setList(page.getRecords());
        return svWorkVoPageData;
    }

    @Override
    public void delMyWork(Long workId) {
        Long userId = SvSecurityUtil.getUserId();
        boolean flag = this.lambdaUpdate()
                .eq(SvWork::getWorkId, workId)
                .eq(SvWork::getUserId, userId)
                .set(SvWork::getIsDel, IsDel.DELETED.getCode()).update();
        if (!flag) BizException.cast("要删除的作品不存在");
    }

    @Override
    public PageData<SvWorkVo> getUserHomeList(SvWorkGetBo svWorkGetBo) {

        if (ObjUtil.equal(WorkGetCategoryEnum.LIKE.getCode(), svWorkGetBo.getCategory())) {
            return new PageData<>();
        }

        if (ObjUtil.equal(WorkGetCategoryEnum.STAR.getCode(), svWorkGetBo.getCategory())) {
            return new PageData<>();
        }

        //校验参数
        if (!EnumUtils.existByValue(WorkGetCategoryEnum::getCode, svWorkGetBo.getCategory())) {
            return new PageData<>();
        }

        if (ObjUtil.isNull(svWorkGetBo.getSort())) {
            svWorkGetBo.setSort(WorkGetSortEnum.TIME.getCode());
        }
        //数据查询
        Page<SvWork> svMyWorkResPage = new Page<>(svWorkGetBo.getPageNum(), svWorkGetBo.getPageSize());
        LambdaQueryWrapper<SvWork> workQueryWrapper = new LambdaQueryWrapper<>();


        if (ObjUtil.equal(svWorkGetBo.getCategory(), WorkGetCategoryEnum.WORK.getCode())) {

            if (ObjUtil.equal(SvSecurityUtil.getUserId(), svWorkGetBo.getUserId())) {
                workQueryWrapper.eq(SvWork::getPer, SvWorkPerEnum.ALL.getCode());
            } else {
                workQueryWrapper.eq(SvWork::getPer, SvWorkPerEnum.ALL.getCode());
                workQueryWrapper.eq(SvWork::getStatus, SvWorkStatusEnum.NORMAL.getCode());
            }
        }


        if (ObjUtil.equal(svWorkGetBo.getCategory(), WorkGetCategoryEnum.PRIVATE.getCode())) {
            workQueryWrapper.eq(SvWork::getPer, SvWorkPerEnum.PRIVACY.getCode());
        }

        if (ObjUtil.equal(svWorkGetBo.getSort(), WorkGetSortEnum.LIKE.getCode())) {
            workQueryWrapper.orderByDesc(SvWork::getLikeNum);
        }


        workQueryWrapper.orderByDesc(SvWork::getCreateTime);
        workQueryWrapper.eq(SvWork::getIsDel, IsDel.NORMAL.getCode());
        workQueryWrapper.eq(SvWork::getUserId, svWorkGetBo.getUserId());
        Page<SvWork> svWorkPage = baseMapper.selectPage(svMyWorkResPage, workQueryWrapper);

        return PageData.setDataCopyVo(svWorkPage, SvWorkVo.class);
    }

    @Override
    public PageData<SvWorkVo> getUserHomeList(SvMyWorkGetBo svMyWorkGetBo) {
        SvWorkGetBo svWorkGetBo = BeanUtil.copyProperties(svMyWorkGetBo, SvWorkGetBo.class);
        svWorkGetBo.setUserId(SvSecurityUtil.getUserId());
        return this.getUserHomeList(svWorkGetBo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void like(Long workId,Long userId) {

        SvWork svWork = getById(workId);
        if (ObjUtil.isNull(svWork) && ObjUtil.equal(svWork.getIsDel(),IsDel.DELETED.getCode())){
            throw new BizException("点赞作品为空");
        }

        //查询我的点赞记录
        LambdaQueryWrapper<SvWorkLike> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SvWorkLike::getUserId, userId);
        lambdaQueryWrapper.eq(SvWorkLike::getWorkId, workId);
        SvWorkLike dbWorkLike = svWorkLikeMapper.selectOne(lambdaQueryWrapper);

        if (ObjUtil.isNull(dbWorkLike)) {
            //如果没有查到说明没有点赞过,就添加点赞记录
            SvWorkLike svWorkLike = new SvWorkLike();
            svWorkLike.setUserId(userId);
            svWorkLike.setWorkId(workId);
            svWorkLikeMapper.insert(svWorkLike);

            //作品点赞+1
            this.lambdaUpdate().eq(SvWork::getWorkId, workId).setSql("like_num = like_num + 1").update();
            LambdaUpdateWrapper<SvUser> svUserUpdate = new LambdaUpdateWrapper<>();
            svUserUpdate.eq(SvUser::getUserId,svWork.getUserId());
            svUserUpdate.setSql("like_num = like_num + 1");
            svUserMapper.update(null,svUserUpdate);
        }


        if (ObjUtil.isNotNull(dbWorkLike)) {
            //如果点赞过,就取消点赞
            svWorkLikeMapper.deleteById(dbWorkLike.getLikeId());

            //作品点赞-1
            this.lambdaUpdate().eq(SvWork::getWorkId, workId).setSql("like_num = like_num - 1").update();
            LambdaUpdateWrapper<SvUser> svUserUpdate = new LambdaUpdateWrapper<>();
            svUserUpdate.eq(SvUser::getUserId,svWork.getUserId());
            svUserUpdate.setSql("like_num = like_num - 1");
            svUserMapper.update(null,svUserUpdate);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void star(Long workId,Long userId) {

        SvWork svWork = getById(workId);
        if (ObjUtil.isNull(svWork) && ObjUtil.equal(svWork.getIsDel(),IsDel.DELETED.getCode())){
            throw new BizException("收藏作品为空");
        }

        //查询我的收藏记录
        LambdaQueryWrapper<SvWorkStar> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SvWorkStar::getUserId, userId);
        lambdaQueryWrapper.eq(SvWorkStar::getWorkId, workId);
        SvWorkStar dbSvWorkStar = svWorkStarMapper.selectOne(lambdaQueryWrapper);


        if (ObjUtil.isNull(dbSvWorkStar)) {
            //如果没有查到说明没有点收藏,就添加收藏记录
            SvWorkStar svWorkStar = new SvWorkStar();
            svWorkStar.setUserId(userId);
            svWorkStar.setWorkId(workId);
            svWorkStarMapper.insert(svWorkStar);

            //作品收藏+1
            this.lambdaUpdate().eq(SvWork::getWorkId, workId).setSql("star_num = star_num + 1").update();
            LambdaUpdateWrapper<SvUser> svUserUpdate = new LambdaUpdateWrapper<>();
            svUserUpdate.eq(SvUser::getUserId,svWork.getUserId());
            svUserUpdate.setSql("star_num = star_num - 1");
            svUserMapper.update(null,svUserUpdate);
        }

        if (ObjUtil.isNotNull(dbSvWorkStar)) {
            //如果收藏过,就取消收藏
            svWorkStarMapper.deleteById(dbSvWorkStar.getStarId());

            //作品收藏—1
            this.lambdaUpdate().eq(SvWork::getWorkId, workId).setSql("star_num = star_num - 1").update();
            LambdaUpdateWrapper<SvUser> svUserUpdate = new LambdaUpdateWrapper<>();
            svUserUpdate.eq(SvUser::getUserId,svWork.getUserId());
            svUserUpdate.setSql("star_num = star_num - 1");
            svUserMapper.update(null,svUserUpdate);
        }

    }

    @Override
    public void perSet(WorkPerSetBo workPerSetBo) {

        if (ObjUtil.isNotNull(workPerSetBo.getPer()) && !EnumUtils.existByValue(SvWorkPerEnum::getCode, workPerSetBo.getPer())) {
            BizException.cast("非法权限参数");
        }

        if (ObjUtil.isNotNull(workPerSetBo.getIsDown()) && !EnumUtils.existByValue(SvWorkIsDown::getIsDown, workPerSetBo.getIsDown())) {
            BizException.cast("非法下载设置参数");
        }

        SvWork svWork = BeanUtil.copyProperties(workPerSetBo, SvWork.class);
        if (!this.updateById(svWork)) {
            BizException.cast(StatusCode.FAIL);
        }

    }

    @Override
    public CosTmpKeyVo getUpTmpKey(String fileName) {

        if (ObjUtil.isEmpty(fileName)) {
            throw new BizException("文件名不能为空");
        }

        int dotIndex = fileName.lastIndexOf(".");

        if (dotIndex == -1) {
            BizException.cast("非法文件名");
        }

        String suffix = fileName.substring(dotIndex);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd/");
        String datePath = LocalDate.now().format(formatter);

        String newFileName = IdUtil.fastSimpleUUID();

        String path = "workVideo/" + datePath + newFileName + suffix;

        return cosService.uploadFileTmpKey(path);
    }

    @Override
    public PageData<SysSvWorkVo> getSysList(SysSvWorkBo svWorkBo) {
        Page<SysSvWorkVo> workVoPage = new Page<>(svWorkBo.getPageNum(), svWorkBo.getPageSize());
        Page<SysSvWorkVo> list = baseMapper.getSysList(workVoPage, svWorkBo);
        return PageData.setData(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void browseWork(Long userId, Long workId) {

        SvWork svWork = this.getById(workId);
        if (ObjUtil.isNull(svWork) && ObjUtil.equal(svWork.getIsDel(),IsDel.DELETED.getCode())) {
            throw new BizException("要浏览的作品不存在");
        }

        SvWorkBrowse svWorkBrowse = new SvWorkBrowse();
        svWorkBrowse.setWorkId(workId);
        svWorkBrowse.setUserId(userId);
        svWorkBrowseMapper.insert(svWorkBrowse);

        svWork.setBrowseNum(svWork.getBrowseNum() + 1);
        this.updateById(svWork);

        LambdaUpdateWrapper<SvUser> svUserLambdaWrapper = new LambdaUpdateWrapper<>();
        svUserLambdaWrapper.eq(SvUser::getUserId,svWork.getUserId());
        svUserLambdaWrapper.setSql("browse_num = browse_num + 1");
        svUserMapper.update(null,svUserLambdaWrapper);
    }

}
















